package com.zc.utils;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zc.Enum.ErrorEnum;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;

import java.text.MessageFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zancong
 * @version V1.0
 * @Description: 自定义响应数据结构
 * 本类可提供给 H5/ios/安卓/公众号/小程序 使用
 * 前端接受此类数据（json object)后，可自行根据业务去实现相关功能
 * <p>
 * 200：表示成功
 * 500：表示错误，错误信息在errorMsg字段中
 * 501：bean验证错误，不管多少个错误都以map形式返回
 * 502：拦截器拦截到用户token出错
 * 555：异常抛出信息
 * 556: 用户qq校验异常
 * @Copyright: Copyright (c) 2020
 * @Company:
 */
public class JSONResult<T> {

    // 定义jackson对象
    private static final ObjectMapper MAPPER = new ObjectMapper();

    // 响应业务状态
    private String errorCode;

    // 响应消息
    private String errorMsg;

    // 响应中的数据
    private T data;

    @JsonIgnore
    private String ok;    // 不使用

    public static JSONResult build(String errorCode, String errorMsg, Object data) {
        return new JSONResult(errorCode, errorMsg, data);
    }

    public static JSONResult build(String errorCode, String errorMsg, Object data, String ok) {
        return new JSONResult(errorCode, errorMsg, data, ok);
    }

    public static <T> JSONResult ok(T data) {
        return new JSONResult(data);
    }

    public static JSONResult ok() {
        return new JSONResult(null);
    }

    public static JSONResult errorErrorMsg(String errorMsg) {
        return new JSONResult("500", errorMsg, null);
    }

    public static JSONResult errorErrorMsg(String errorCode, String errorMsg) {
        return new JSONResult(errorCode, errorMsg, null);
    }

    /**
     * 处理Controller参数校验错误信息
     *
     * @param errorEnum
     * @param bindingResult
     * @return
     */
    public static JSONResult errorMsg(ErrorEnum errorEnum, BindingResult bindingResult) {
        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
        Map<String, String> stringMap = new HashMap<>();
        for (FieldError fieldError : fieldErrors) {
            stringMap.put(fieldError.getField(), fieldError.getDefaultMessage());
        }
        return new JSONResult(errorEnum.getErrorCode(), MessageFormat.format(errorEnum.getErrorMsg(), stringMap.toString()), null);
    }

    /**
     * 处理错误信息,并返回数据
     *
     * @param errorEnum
     * @param t
     * @return
     */
    public static <T> JSONResult errorMsg(ErrorEnum errorEnum, T t) {
        return new JSONResult(errorEnum.getErrorCode(), errorEnum.getErrorMsg(), t);
    }

    /**
     * 处理错误信息中有占位符的情况
     *
     * @param errorEnum
     * @param params
     * @return
     */
    public static JSONResult errorMsg(ErrorEnum errorEnum, String... params) {
        return new JSONResult(errorEnum.getErrorCode(), MessageFormat.format(errorEnum.getErrorMsg(), params), null);
    }

    /**
     * 处理错误信息中有占位符的情况
     *
     * @param errorCode
     * @param errorMsg
     * @param params
     * @return
     */
    public static JSONResult errorMsg(String errorCode, String errorMsg, String... params) {
        return new JSONResult(errorCode, MessageFormat.format(errorMsg, params), null);
    }

    public static JSONResult errorMap(Object data) {
        return new JSONResult("501", "error", data);
    }

    public static JSONResult errorTokenErrorMsg(String errorMsg) {
        return new JSONResult("502", errorMsg, null);
    }

    public static JSONResult errorException(String errorMsg) {
        return new JSONResult("555", errorMsg, null);
    }

    public static JSONResult errorUserQQ(String errorMsg) {
        return new JSONResult("556", errorMsg, null);
    }

    public JSONResult() {

    }

    public JSONResult(String errorCode, String errorMsg, T data) {
        this.errorCode = errorCode;
        this.errorMsg = errorMsg;
        this.data = data;
    }

    public JSONResult(String errorCode, String errorMsg, T data, String ok) {
        this.errorCode = errorCode;
        this.errorMsg = errorMsg;
        this.data = data;
        this.ok = ok;
    }

    public JSONResult(T data) {
        this.errorCode = ErrorEnum.S_SUCCESS.errorCode;
        this.errorMsg = ErrorEnum.S_SUCCESS.getErrorMsg();
        this.data = data;
    }

    public boolean isOK() {
        if(this.errorCode == ErrorEnum.S_SUCCESS.errorCode){
            return true;
        }else {
            return false;
        }
    }

    public String getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(String errorCode) {
        this.errorCode = errorCode;
    }

    public String getErrorMsg() {
        return errorMsg;
    }

    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public String getOk() {
        return ok;
    }

    public void setOk(String ok) {
        this.ok = ok;
    }

    @Override
    public String toString() {
        return "JSONResult{" +
                "errorCode='" + errorCode + '\'' +
                ", errorMsg='" + errorMsg + '\'' +
                ", data=" + data +
                ", ok='" + ok + '\'' +
                '}';
    }
}

